#include <iostream>
#include <string>
#include <list>
using namespace std;

// class Person
// {
// public:
//     virtual void BuyTicket()
//     {
//         cout << "买票-全价" << endl;
//     }
// };

// class Student:public Person
// {
// public:
//     virtual void BuyTicket()
//     {
//         cout << "买票-半价" << endl;
//     }
// };

// void test(Person& p)
// {
//     p.BuyTicket();
// }

// int main()
// {
//     Person p;
//     Student s;
//     test(p);
//     test(s);
//     return 0;
// }

// class A
// {
// public:
//     A()
//     {
//         //cout << "A()" << endl;
//     }
// };

// class B : public A
// {
// public:
//     B()
//     {
//         //cout << "B()" << endl;
//     }
// };

// class Person
// {
// public:
//     virtual A* f()
//     {
//         cout << "A* f()" << endl;
//         return new A;
//     }
//     virtual ~Person()
//     {
//         cout << "~Person()" << endl;
//     }

// };

// class Student : public Person
// {
// public:
//     virtual B* f()
//     {
//         cout << "B* f()" << endl;
//         return new B;
//     }

//     virtual ~Student()
//     {
//         cout << " ~Student() " << endl;
//     }
// };

// void test(Person& p)
// {
//     p.f();
// }

// int main()
// {
//     // Person p;
//     // Student s;
//     // //test(p);
//     // test(s);

//     Person* p1 = new Person;
//     delete p1;
//     Person* p2 = new Student;
//     delete p2;
//     return 0;
// }


// class base
// {
// public:
//     virtual void func1()
//     {
//         cout << "base::func1" << endl;
//     }
//     virtual void func2()
//     {
//         cout << "base::func1" << endl;
//     }
//     void func3()
//     {
//         cout << "base::func1" << endl;
//     }
// private:
//     int _b = 1;
//     int _ch;
// };

// class derive : public base 
// {
// public:
//     virtual void func1()
//     {
//         cout << "derive::func1" << endl;
//     }
// private:
//     int _d = 2;
// };


// void test(base& b)
// {
//     b.func1();
// }


// int main()
// {
//     base b;
//     cout << sizeof(b) << endl;
//     derive d;
//     cout << sizeof(b) << endl;

//     test(b);
//     test(d);

//     d.func3();

//     return 0;
// }


// class Car
// {
// public:
//     virtual void Drive() = 0;
// };

// //间接强制子类重写虚函数，不重写虚函数，子类依旧是抽象类不能
// //实例化对象
// class Benz: public Car
// {
// public:
//     virtual void Drive()
//     {
//         cout << "Benz-舒适" << endl;
//     }
// };


// class BWM: public Car
// {
// public:
//     virtual void Drive()
//     {
//         cout << "BWM-操控" << endl;
//     }
// };

// int main()
// {
//     //Car c;
//     Car* c = new Benz;
//     c->Drive();
//     return 0;
// }

class base
{
public:
    virtual void func1()
    {
        cout << "base::func1" << endl;
    }
    virtual void func2()
    {
        cout << "base::func1" << endl;
    }
    void func3()
    {
        cout << "base::func1" << endl;
    }
private:
    int _b = 1;
};

class derive: public base
{
public:
    virtual void func1()
    {
        cout << "derive::func1()" << endl;
    }
    virtual void func3()
    {
        cout << "derive::func1" << endl;
    }
private:
    int _b = 1;
};

typedef void(*VF_PTR)();

//打印虚表
void printVFT(VF_PTR vft[],int num)
{
    for(size_t i = 0; i < num; i++)
    {
        printf("[%d]:%p\n",i,vft[i]);
        VF_PTR f = vft[i];
        f();
    }
}


// int main()
// {
//     derive d;
//     derive* pd = &d;
//     printVFT((VF_PTR*)(*(long long*)pd),2);

//     base b;
//     base* pb = &d;
//     printVFT((VF_PTR*)(*(long long*)pb),2);

//     return 0;   
// }  


int main()
{
    int i = 0;
    printf("栈: %p\n",&i);
    static int j = 1;
    printf("静态区: %p\n",&j);
    int*p1 = new int;
    printf("堆: %p\n",p1);
    const char* p2 = "xxxxxxxx";
    printf("常量区: %p\n",p2);

    base b;
    base* pb = &b;
    long long* p3 = (long long*)pb;
    printf("base虚表地址: %p\n",*p3);
    //printf("虚函数表: %p\n",*(int*)pb);
    derive d;
    derive* pd = &d;
    long long* p4 = (long long*)pd;
    printf("derive虚表地址: %p\n",*p4);
    return 0;
}
